package com.hmall.search.test;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hmall.search.mapper.ItemMapper;
import com.hmall.search.pojo.Item;
import com.hmall.search.pojo.ItemDoc;
import lombok.SneakyThrows;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@SpringBootTest
public class test {


    @Autowired(required = false)
    RestHighLevelClient HighLevelClient;

    @Autowired(required = false)
    ItemMapper itemMapper;

    @Autowired(required = false)
    private ObjectMapper objectMapper =new ObjectMapper();

    //删除索引库
    @Test
    public void testDeleteIndex() throws IOException {
        IndicesClient indicesClient = HighLevelClient.indices();

        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("item");

        AcknowledgedResponse response = indicesClient.delete(deleteIndexRequest, RequestOptions.DEFAULT);

        System.out.println(response.isAcknowledged());
        System.out.println("索引库已删除");
    }

    /**
     *创建索引库
     */
    @Test
    public void testIndex() throws IOException {
        //1.获取创建索引仓库客户端对象
        IndicesClient indices = HighLevelClient.indices();

        //2.创建索引库内存对象
        CreateIndexRequest item = new CreateIndexRequest("item");

        //3、添加映射
        String mapping = "{\n" +
                " \"properties\": {\n" +
                "   \"id\":{\n" +
                "  \"type\": \"keyword\"\n" +
                "   },\n" +
                "   \"name\":{\n" +
                "  \"type\": \"text\",\n" +
                "  \"analyzer\": \"text_analyzer\",\n" +
                "  \"search_analyzer\": \"ik_smart\",\n" +
                "  \"copy_to\": \"all\"\n" +
                "   },\n" +
                "   \"price\":{\n" +
                "  \"type\": \"long\"\n" +
                "   },\n" +
                "   \"image\":{\n" +
                "  \"type\": \"keyword\",\n" +
                "  \"index\": false\n" +
                "   },\n" +
                "   \"category\":{\n" +
                "  \"type\": \"keyword\",\n" +
                "  \"copy_to\": \"all\"\n" +
                "   },\n" +
                "   \"brand\":{\n" +
                "  \"type\": \"keyword\",\n" +
                "  \"copy_to\": \"all\"\n" +
                "   },\n" +
                "   \"sold\":{\n" +
                "  \"type\": \"integer\"\n" +
                "   },\n" +
                "   \"commentCount\":{\n" +
                "  \"type\": \"integer\"\n" +
                "   },\n" +
                "   \"isAD\":{\n" +
                "  \"type\": \"boolean\"\n" +
                "   },\n" +
                "   \"suggestion\":{\n" +
                "    \"type\": \"completion\",\n" +
                "    \"analyzer\": \"completion_analyzer\",\n" +
                "    \"search_analyzer\": \"keyword\"\n" +
                "   },\n" +
                "   \"all\":{\n" +
                "  \"type\": \"text\",\n" +
                "  \"analyzer\": \"text_analyzer\",\n" +
                "  \"search_analyzer\": \"ik_smart\"\n" +
                "   }\n" +
                " }\n" +
                "  }";
        item.mapping(mapping,XContentType.JSON);
        //hotel.mapping(mapping, XContentType.JSON);
        String setting = "{\n" +
                "  \"index\":{\n" +
                "    \"max_result_window\": 500000\n" +
                "  },\n" +
                " \"analysis\": {\n" +
                "   \"analyzer\": {\n" +
                "  \"text_analyzer\": {\n" +
                "    \"tokenizer\": \"ik_max_word\",\n" +
                "    \"filter\": \"py\"\n" +
                "  },\n" +
                "  \"completion_analyzer\": {\n" +
                "    \"tokenizer\": \"keyword\",\n" +
                "    \"filter\": \"py\"\n" +
                "  }\n" +
                "   },\n" +
                "   \"filter\": {\n" +
                "  \"py\": {\n" +
                "    \"type\": \"pinyin\",\n" +
                "    \"keep_full_pinyin\": false,\n" +
                "    \"keep_joined_full_pinyin\": true,\n" +
                "    \"keep_original\": true,\n" +
                "    \"limit_first_letter_length\": 16,\n" +
                "    \"remove_duplicated_term\": true,\n" +
                "    \"none_chinese_pinyin_tokenize\": false\n" +
                "  }\n" +
                "   }\n" +
                " }\n" +
                "  }";
        item.settings(setting,XContentType.JSON);
        //3.根据索引库内存对象执行DSL命令到ES服务器端创建索引库对象
        CreateIndexResponse response = indices.create(item,RequestOptions.DEFAULT);
        //4.打印命令执行结果
        System.out.println(response.isAcknowledged());
        System.out.println("索引库已建立");
    }



    
    /**
     * 批量添加
     */
    @Test
    public void testBulkRrquest() throws IOException {
        //1.调用 hotelMapper 查询所有数据返回集合 List<Hotel>
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        long startTime = System.currentTimeMillis();
        //
        //ExecutorService executor = Executors.newFixedThreadPool(10);
        Page<Item> page = new Page<>(100, 1);
        QueryWrapper queryWrapper = new QueryWrapper<>();

        itemMapper.selectPage(page, queryWrapper);

        List<Item> itemList = page.getRecords();
        
        //2.判断集合是否不为空，工具类 CollectionUtils.isNotEmpty(集合)
        // 工具类： CollectionUtils.isNotEmpty(集合)
        // 注意： 这里引入的是 MP中的CollectionUtils 工具类
        if (CollectionUtils.isNotEmpty(itemList)){

            //3.创建批量操作请求对象 BulkRequest
            BulkRequest bulkRequest = new BulkRequest();

            //4.遍历 List<Hotel> 集合每元素数据
            for (Item item:itemList){
                //4.1.将每个 hotel 对象封装层 hotelDoc 对象
                ItemDoc itm_es = new ItemDoc(item);
                //4.2 根据hotelDoc对象数据，构建添添加文档数据的请求对象 IndexRequest 对象
                //    本质：构建每个数据的添加文档命令，格式为: POST 索引库名/_doc
                IndexRequest request = new IndexRequest("item").id(itm_es.getId().toString());
                //4.3 将 hotelDoc 对象转换为json字符串，并通过request对象source方法封装json数据
                //    本质：构建每个数据的添加文档命令，格式为: POST 索引库名/_doc{文档数据}
                String json = objectMapper.writeValueAsString(itm_es);
                request.source(json, XContentType.JSON);
                //4.4 将请求对象 IndexRequest(每个添加文档命令) 添加到批量操作请求对象 BulkRequest 中
                bulkRequest.add(request);
            }
            //5.批量执行添加命令
            HighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            while (!executorService.isTerminated()) { } long endTime = System.currentTimeMillis();
            System.out.println("Total execution time: " + (endTime - startTime) + "ms");
        }
    }


    /**
     * 多线程批量添加
     */
    @Test public void testMultiThreadBulkRequest() throws IOException {

        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //记录运行开始时间
        long startTime = System.currentTimeMillis();

        //
        for (int i=1; i < 100; i++) {
            //查询sql数据库数据
            Page<Item> page = new Page<>(i , 842);
            executorService.submit(new Runnable( ) {
                @SneakyThrows
                @Override
                public void run() {
                    QueryWrapper queryWrapper = new QueryWrapper<>();
                    itemMapper.selectPage(page, queryWrapper);
                    List<Item> itemList = page.getRecords();
                    if (CollectionUtils.isNotEmpty(itemList)){
                        BulkRequest bulkRequest = new BulkRequest();
                        for (Item item:itemList){
                            ItemDoc itm_es = new ItemDoc(item);
                            IndexRequest request = new IndexRequest("item").id(itm_es.getId().toString());
                            String json = objectMapper.writeValueAsString(itm_es);
                            request.source(json, XContentType.JSON);
                            bulkRequest.add(request);
                        }
                        HighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
                    }
                }
            });
        }
        executorService.shutdown();
        while (!executorService.isTerminated()) { } long endTime = System.currentTimeMillis();
        System.out.println("Total execution time: " + (endTime - startTime) + "ms");
        System.out.println("Total execution time: " + (endTime - startTime) + "ms");
        System.out.println("Total execution time: " + (endTime - startTime) + "ms");
    }
}
